package com.chunlin.map;

import com.chunlin.Employee;

import java.util.*;

public class HashMapTest {
    //1. HashMap 和 HashSet 即 java 中利用哈希表实现的 Map 和 Set
    //2. java 中使用的是哈希桶方式解决冲突的
    //3. java 会在冲突链表长度大于一定阈值后，将链表转变为搜索树（红黑树）
    //4. java 中计算哈希值实际上是调用的类的 hashCode 方法
    // 进行 key 的相等性比较是调用 key 的 equals 方法
    // 所以如果要用自定义类作为 HashMap 的 key 或者 HashSet 的值
    // 必须覆写 hashCode 和 equals 方法，而且要做到 equals 相等的对象，hashCode 一定是一致的
    //5. HashMap 和 HashSet 都不保证元素的迭代顺序，且此顺序可能随时间改变
    // 如果需要顺序保持一致，应该使用 LinkedHashMap 或 LinkedHashSet，它们维护元素的插入顺序
    //LinkedHashSet 基于 LinkedHashMap，这是 HashMap 的一个特殊版本
    //当在 LinkedHashSet 中插入一个新元素时，元素首先被插入 LinkedHashMap 的哈希表中
    //如果这是一个新条目（即哈希表中还没有这个元素的键），则它将被添加到双向链表的末尾
    //这个新条目在双向链表中的位置将与其他元素相连，通过 before 和 after 指针来链接前一个和后一个元素，从而保持插入的顺序
    //当从 LinkedHashSet 中删除元素时，该元素会从哈希表和双向链表中同时被移除
    //删除操作涉及调整被删除元素前后元素的链接指针，确保链表的连续性
    //迭代 LinkedHashSet 时，迭代器遵循双向链表的顺序，从头到尾遍历所有元素
    //这保证了无论哈希表的状态如何变化，元素的迭代顺序总是反映它们最初添加到集合中的顺序
    public static void main(String[] args) {
        test1();
    }

    private static void test1() {
        HashMap<Employee, String> map = new HashMap<>();
        // 创建员工对象
        Employee e1 = new Employee(1, "Alice");
        Employee e2 = new Employee(2, "Bob");

        // put 操作
        map.put(e1, "Department A");
        map.put(e2, "Department B");

        // get 操作
        System.out.println("e1's Department: " + map.get(e1));
        System.out.println("e2's Department: " + map.get(e2));

        // containsKey 和 containsValue 操作
        System.out.println("Contains Key e1: " + map.containsKey(e1));
        System.out.println("Contains Value 'Department A': " + map.containsValue("Department B"));

        // remove 操作
        map.remove(e1);
        System.out.println("After removing e1, contains Key e1: " + map.containsKey(e1));

        //size 和 isEmpty 操作
        System.out.println("Size of map: " + map.size());
        System.out.println("Is map empty: " + map.isEmpty());

        //批量添加更多员工
        HashMap<Employee, String> newEmployees = new HashMap<>();
        Employee e3 = new Employee(3, "Charlie");
        Employee e4 = new Employee(4, "Diana");
        newEmployees.put(e3, "Department C");
        newEmployees.put(e4, "Department D");
        map.putAll(newEmployees);

        // 输出整个映射,需要重写toString函数
        System.out.println("Complete Map: " + map);

        // 集合视图进行遍历
        Set<Employee> key = map.keySet();
        Iterator<Employee> iterator = key.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next() + " ");
        }

        Collection<String> value = map.values();
        Iterator<String> iterator1 = value.iterator();
        System.out.println();
        while (iterator1.hasNext()) {
            System.out.println(iterator1.next() + " ");
        }
        System.out.println();

        Set<Map.Entry<Employee, String>> entrySet = map.entrySet();
        Iterator<Map.Entry<Employee, String>> iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Map.Entry<Employee, String> entry = iterator2.next();
            System.out.println(entry.getKey() + " -> " + entry.getValue() + " ");
        }
        System.out.println();

    }
}
